Redis 核心数据结构与命令
Redis 系统讲解第一篇:把五大类型的命令讲全,再补上"01 路线篇"没展开的键设计与底层编码对应关系。01 篇是"高频命令体感",这一篇是"全景地图"——忘了哪个命令,先来这里查。
键设计:先定规范再写代码
Redis 只有 key-value 两层,业务语义全靠 key 的命名约定:
业务域:对象:ID:字段 —— 冒号分层是社区通用惯例
user:1:profile # 用户 1 的资料(Hash)
order:202608:count # 8 月订单计数(String/INCR)
sign:user:1:202608 # 用户 1 的 8 月签到(Bitmap)
三条红线:
- key 别太长也别太短:太长占内存(key 本身也是数据),太短没语义。100 字节以内为佳。
- 警惕大 key:单个 value 太大(如一个 10 万元素的 List、几 MB 的 String)——读写阻塞单线程、删除卡顿(用
UNLINK异步删代替DEL)、迁移卡顿。发现手段:redis-cli --bigkeys。 - 警惕热 key:某个 key 被疯狂访问(秒杀商品)——单线程模型下它是瓶颈。解法:本地缓存兜一层、key 加随机后缀拆多份。
String:最全命令与场景
| 命令 | 作用 | 场景备注 |
|---|---|---|
SET key val [EX 秒] [NX|XX] [KEEPTTL] |
写入 | NX=不存在才写;XX=存在才写;KEEPTTL 保留原 TTL |
GET / MGET / MSET |
读 / 批量读 / 批量写 | MGET 一次网络往返拿 N 个,比循环 GET 快 |
INCR / INCRBY / INCRBYFLOAT |
原子自增 | 计数器、限流、分布式 id 雏形 |
APPEND / STRLEN |
追加 / 长度 | value 是字符串语义时用 |
SETNX |
不存在才写 | 老式锁写法,已被 SET NX EX 取代 |
GETRANGE / SETRANGE |
读子串 / 覆写子串 | 偏移量操作 |
注意:Redis 的 String 是二进制安全的——存图片字节、序列化后的 JSON 都行,上限 512MB。
Hash
HSET user:1 name "张三" age 21 # 多 field 一次写
HGET / HMGET / HGETALL # 单取 / 多取 / 全取
HDEL field / HKEYS / HVALS / HLEN # 删 field / 全部 field / 全部 value / 长度
HINCRBY user:1 age 1 # field 级原子自增——对象内计数很顺手
场景:对象缓存(比整个 JSON 塞 String 好改单字段)、购物车(field=商品 id,value=数量)。
List
LPUSH / RPUSH / LPOP / RPOP # 双端进出
LRANGE key 0 -1 # 全量;负数下标从尾数
LLEN / LINDEX / LSET / LTRIM # 长度 / 按下标取 / 按下标赋值 / 修剪保长度
BLPOP / BRPOP key 5 # 阻塞弹出,5 秒等不到才放弃
场景:最新消息列表(LTRIM 保留前 N 条=固定窗口)、简单队列。
Set
SADD / SREM / SISMEMBER / SCARD # 增 / 删 / 判存 / 计数
SMEMBERS # 全部成员——大集合慎用,用 SSCAN 渐进
SINTER / SUNION / SDIFF # 交 / 并 / 差(共同关注、推荐)
SRANDMEMBER / SPOP # 随机看不取 / 随机弹出
ZSet
ZADD rank 95 "张三" # score member
ZINCRBY / ZSCORE / ZCARD # 加分 / 查分 / 总数
ZREVRANGE rank 0 9 WITHSCORES # 排行榜 top10
ZRANK / ZREVRANK # 正序 / 逆序排名
ZRANGEBYSCORE rank 90 (100 WITHSCORES # 区间查询,( 表示开区间
ZREMRANGEBYSCORE rank -inf 60 # 删 60 分以下(定期清理老数据常用)
ZSet 是 Redis 最"值钱"的结构:排行榜、延迟队列(score 存执行时间戳)、滑动窗口限流都靠它。
通用命令与键管理
SCAN 0 MATCH user:* COUNT 100 # 渐进遍历,生产唯一正确姿势
EXPIRE / PEXPIRE / TTL / PTTL # 秒级 / 毫秒级过期与查看
PERSIST key # 去掉 TTL
OBJECT ENCODING key # 看底层编码(见下表)
TYPE key # 看类型
RANDOMKEY / DBSIZE / FLUSHDB # 随机 key / 库大小 / 清库
type 与 encoding:同一类型多种底层实现
TYPE 是对外逻辑类型,OBJECT ENCODING 是底层真实结构——Redis 会按数据大小自动切换编码,这是它省内存的秘诀之一:
| TYPE | 小数据编码 | 大数据编码 |
|---|---|---|
| string | int(整数)/ embstr(短字符串) | raw(长字符串) |
| hash | listpack(field 少且短) | hashtable |
| list | listpack | quicklist(双向链表套 listpack) |
| set | intset(全整数时) | listpack / hashtable |
| zset | listpack | skiplist + dict 双结构 |
💡 阈值由配置里的
*-max-listpack-entries / *-max-listpack-value控制。记忆钩子:Redis 总是先用紧凑结构省内存,超阈值自动升级——理解这一点,"为什么我的 hash 存了 130 个字段变慢"这类问题就有了方向。
键过期与淘汰的完整图景
- 过期删除:惰性删除(访问时检查)+ 定期删除(后台抽样清理)组合
- 内存淘汰:内存达到
maxmemory后按maxmemory-policy淘汰——noeviction(默认,写报错)/ allkeys-lru / volatile-lru / allkeys-lfu / volatile-lfu / allkeys-random / volatile-random / volatile-ttl - 我的选择锚点:纯缓存选
allkeys-lru(或热点更集中的allkeys-lfu);key 里混着"不能丢"的数据才用volatile-*(只淘汰带 TTL 的)
⬅️ 01-Redis 学习路线 🏠 00-数据库 ➡️ 03-Redis 应用实战
💬 评论